package control;

import databasehandling.HandlerFactory;
import databasehandling.SalgsHandler;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import model.Billet;
import model.BilletSalg;
import model.Event;
import model.EventSalg;
import model.Salg;
import model.Vare;
import model.VareSalg;
import utility.DebugUtility;

public class SalgsController {

    private static SalgsController instance;
    private final SalgsHandler salgsHandler;
    private Salg aktivtSalg;

    private SalgsController() {
        salgsHandler = HandlerFactory.getInstance().getSalgsHandler();
    }

    public static SalgsController getInstance() {
        if (instance == null) {
            instance = new SalgsController();
        }
        return instance;
    }

    //<editor-fold defaultstate="collapsed" desc="Tilføj/Fjern vare, Billet og Event til salg">
    /**
     * Tilføjer en vare til det aktive salgs varesalgsliste. 
     * Metoden tjekker om varen i forvejen er tilføjet, i så fald tilføjes varen med det kaldte antal.
     * Bliver antal 0 fjernes varen fra listen.
     * Er varen ikke allerede tilføjet, tilføjes den som en ny i listen.
     * @param vare 
     * @param antal 
     * @param salgsPris
     * @param rabat 
     */
    public void tilføjVareTilSalg(Vare vare, int antal, int salgsPris, int rabat) {
        boolean vareAlleredeTilføjetTilSalg = false;
        for (int i = 0; i < aktivtSalg.getVareSalgsListe().size(); i++) {
            if (aktivtSalg.getVareSalgsListe().get(i).getVare().getVarenummer() == vare.getVarenummer()) {
                vareAlleredeTilføjetTilSalg = true;
                aktivtSalg.getVareSalgsListe().get(i).setAntal(aktivtSalg.getVareSalgsListe().get(i).getAntal() + antal);
                if (aktivtSalg.getVareSalgsListe().get(i).getAntal() == 0) {
                    aktivtSalg.getVareSalgsListe().remove(i);
                }
            }

        }
        if (!vareAlleredeTilføjetTilSalg) {
            aktivtSalg.getVareSalgsListe().add(new VareSalg(antal, salgsPris, rabat, vare));
        }
        DebugUtility.getInstance().soutDebugLine(this, 1, "Antal varer i aktivtSalg: " + aktivtSalg.getVareSalgsListe().size());
        if (!aktivtSalg.getVareSalgsListe().isEmpty()) {
            DebugUtility.getInstance().soutDebugLine(this, 1, "Antal varer af den første vare i vareListen på salget: " + aktivtSalg.getVareSalgsListe().get(0).getAntal());
        }

    }

    /**
     * Tilføjer en billet til det aktive salgs billetsalgsliste. 
     * Metoden tjekker om billettypen (Barn, Voksen eller Gratist) i forvejen er tilføjet, i så fald tilføjes den med det kaldte antal.
     * Bliver antal 0 fjernes billetten fra listen.
     * Er billetten ikke allerede tilføjet, tilføjes den som en ny i listen.
     * @param billet
     * @param antal
     * @param salgsPris
     * @param valutaDKK
     * @param rabat
     * @throws SQLException 
     */
    public void tilføjBilletTilSalg(Billet billet, int antal, int salgsPris, boolean valutaDKK, int rabat) throws SQLException {
        boolean billetAlleredeTilføjetTilSalg = false;
        for (int i = 0; i < aktivtSalg.getBilletSalgsListe().size(); i++) {
            if (aktivtSalg.getBilletSalgsListe().get(i).getBillet().getId() == billet.getId()) {
                billetAlleredeTilføjetTilSalg = true;
                aktivtSalg.getBilletSalgsListe().get(i).setAntal(aktivtSalg.getBilletSalgsListe().get(i).getAntal() + antal);
                if (aktivtSalg.getBilletSalgsListe().get(i).getAntal() == 0) {
                    aktivtSalg.getBilletSalgsListe().remove(i);
                }
            }
        }
        if (!billetAlleredeTilføjetTilSalg) {
            aktivtSalg.getBilletSalgsListe().add(new BilletSalg(antal, salgsPris, valutaDKK, rabat, billet));
        }
    }

    /**
     * Tilføjer et event til det aktive salgs eventsalgsliste.
     * Metoden tjekker, at det event der kaldes med ikke allerede er tilføjet, ellers tilføjes det og variablen antalFremmødte
     * bliver sat med det pågældende antal
     * @param event
     * @param antalFremmødte
     * @param rabat 
     */
    public void tilføjEventTilSalg(Event event, int antalFremmødte, int rabat) {
        aktivtSalg.setValutaDKK(true);
        boolean eventAlleredeTilføjetTilSalg = false;
        for (int i = 0; i < aktivtSalg.getEventSalgsListe().size(); i++) {
            if (aktivtSalg.getEventSalgsListe().get(i).getEvent().getId() == event.getId()) {
                eventAlleredeTilføjetTilSalg = true;
            }

        }
        if (!eventAlleredeTilføjetTilSalg) {
            aktivtSalg.getEventSalgsListe().add(new EventSalg(event.getEventType().getPrisDKK(), rabat, event));
            event.setAntalFremmødte(antalFremmødte);
        }
    }

    public void fjernVareFraSalg(VareSalg vareSalg) {
        aktivtSalg.getVareSalgsListe().remove(vareSalg);
    }

    public void fjernBilletFraSalg(BilletSalg billetSalg) {
        aktivtSalg.getBilletSalgsListe().remove(billetSalg);
    }

    public void fjernEventFraSalg(EventSalg eventSalg) {
        aktivtSalg.getEventSalgsListe().remove(eventSalg);
    }

//</editor-fold>
    /**
     * Afslutter det aktive salg, gennemløber salgets salgslister og gemmer dem i databasen
     * @throws SQLException 
     */
    public void afslutSalg() throws SQLException {
        salgsHandler.opretSalg(aktivtSalg, AnsatController.getInstance().getAktivAnsat(), KasseController.getInstance().getAktivKasse());
        for (int i = 0; i < aktivtSalg.getVareSalgsListe().size(); i++) {
            VareSalg vs = aktivtSalg.getVareSalgsListe().get(i);
            salgsHandler.tilføjVareTilSalg(vs, aktivtSalg);
        }
        for (int i = 0; i < aktivtSalg.getBilletSalgsListe().size(); i++) {
            BilletSalg bs = aktivtSalg.getBilletSalgsListe().get(i);
            salgsHandler.tilføjBilletTilSalg(bs, aktivtSalg);
        }
        for (int i = 0; i < aktivtSalg.getEventSalgsListe().size(); i++) {
            EventSalg es = aktivtSalg.getEventSalgsListe().get(i);
            salgsHandler.tilføjEventTilSalg(es, aktivtSalg);
        }
        salgsHandler.afslutSalg(aktivtSalg);
    }

    @Deprecated
    //<editor-fold defaultstate="collapsed" desc="Bruges ikke umiddelbart">
    /**
     * Beregning og opdatering af totalBeløb på det aktive salgs-objekt
     *
     * @param valutaDKK true hvis valuta skal være danske kroner.
     */
    private void beregnTotalBeløb(boolean valutaDKK) {
        aktivtSalg.setValutaDKK(valutaDKK);
        int result = 0;
        for (int i = 0; i < aktivtSalg.getVareSalgsListe().size(); i++) {
            Vare vare = aktivtSalg.getVareSalgsListe().get(i).getVare();
            if (aktivtSalg.isValutaDKK()) {
                result = result + (vare.getUdsalgsprisDKKMedRabat() * aktivtSalg.getVareSalgsListe().get(i).getAntal());
            } else {
                result = result + (vare.getUdsalgsprisEUROMedRabat() * aktivtSalg.getVareSalgsListe().get(i).getAntal());
            }
        }
        for (int i = 0; i < aktivtSalg.getBilletSalgsListe().size(); i++) {
            Billet billet = aktivtSalg.getBilletSalgsListe().get(i).getBillet();
            if (aktivtSalg.isValutaDKK()) {
                result = result + (billet.getPrisDKK() * aktivtSalg.getBilletSalgsListe().get(i).getAntal());
            } else {
                result = result + (billet.getPrisEURO() * aktivtSalg.getBilletSalgsListe().get(i).getAntal());
            }
        }
        for (int i = 0; i < aktivtSalg.getEventSalgsListe().size(); i++) {
            Event event = aktivtSalg.getEventSalgsListe().get(i).getEvent();
            if (aktivtSalg.isValutaDKK()) {
                result = result + (event.getEventType().getPrisDKK());
            } else {
                result = result + (event.getEventType().getPrisEURO());
            }
        }
        result = result - (result / 100 * aktivtSalg.getRabat());
        aktivtSalg.setTotalBeløb(result);
    }
//</editor-fold>

    /**
     * Tilføjer rabat på hele salget og beregner det nye totalbeløb som returneres
     * @param rabat
     * @return  
     */
    public int tilføjRabatPåSalg(int rabat) {
        int result;
        aktivtSalg.setRabat(rabat);
        result = aktivtSalg.beregnTotalBeløb();
        return result;
    }

    public Salg getAktivtSalg() {
        return aktivtSalg;
    }

    //<editor-fold defaultstate="collapsed" desc="setAktivtSalg">
    public void setAktivtSalg(Salg aktivtSalg) {
        this.aktivtSalg = aktivtSalg;
    }
//</editor-fold>

    public void lavNytSalg() {
        aktivtSalg = new Salg(Calendar.getInstance(), AnsatController.getInstance().getAktivAnsat(), KasseController.getInstance().getAktivKasse());
    }

    public static int beregnTotalBeløbPåVareSalgsListe(ArrayList<VareSalg> vareSalgsListe) {
        int totalBeløb = 0;
        for (int i = 0; i < vareSalgsListe.size(); i++) {
            totalBeløb = totalBeløb + vareSalgsListe.get(i).getSalgsprisMedRabat();
        }
        return totalBeløb;
    }

    public static int beregnTotalBeløbPåBilletSalgsListe(ArrayList<BilletSalg> billetSalgsListe) {
        int totalBeløb = 0;
        for (int i = 0; i < billetSalgsListe.size(); i++) {
            totalBeløb = totalBeløb + billetSalgsListe.get(i).getSalgsprisMedRabat();
        }
        return totalBeløb;
    }

    public static int beregnTotalBeløbPåEventSalgsListe(ArrayList<EventSalg> eventSalgsListe) {
        int totalBeløb = 0;
        System.out.println("Størrelse på liste " +eventSalgsListe.size());
        for (int i = 0; i < eventSalgsListe.size(); i++) {
            totalBeløb = totalBeløb + eventSalgsListe.get(i).getSalgsprisMedRabat();
            System.out.println(totalBeløb);
        }
        return totalBeløb;
    }
}
